package com.accounting.client.frontend.order;

import java.util.ArrayList;
import java.util.List;

import com.accounting.client.ApplicationContext;
import com.accounting.client.frontend.order.handlers.OrderPackageHandler;
import com.accounting.client.remote.Services;
import com.accounting.client.remote.enumeration.Courier;
import com.accounting.client.remote.enumeration.OrderStatues;
import com.accounting.client.remote.obj.Order;
import com.accounting.client.remote.transfer.SearchOrderRequest;
import com.accounting.client.resource.BoxResources;
import com.accounting.client.session.ErrorHandler;
import com.accounting.client.session.SessionManager;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;

import corelib.client.NumberFormats;
import corelib.client.Util;
import corelib.client.date.DateFormats;
import corelib.client.delegate.Action;
import corelib.client.delegate.DataCallback;
import corelib.client.resource.CommonResources;
import corelib.client.schedule.DeferredTask;
import corelib.client.search.PagingResult;
import corelib.client.ui.SimpleModal;
import corelib.client.ui.widget.SimpleDataModel;
import corelib.client.ui.widget.WidgetListener;
import corelib.client.ui.widget.dialog.SimpleDialog;
import corelib.client.ui.widget.dialog.SimpleLargeDialog;
import corelib.client.ui.widget.form.SimpleLabel;
import corelib.client.ui.widget.grid.SimpleDataGrid;
import corelib.client.ui.widget.grid.SimpleDataGridHandler;
import corelib.client.ui.widget.grid.cell.CellRenderer;
import corelib.client.ui.widget.grid.column.ColumnConfig;
import corelib.client.ui.widget.grid.column.ColumnConfigs;
import corelib.client.ui.widget.messagebox.SimpleMessageBox;
import corelib.client.ui.widget.page.PageBase;
import corelib.client.ui.widget.panel.SimpleLayoutPanel;
import corelib.client.ui.widget.toolbar.SimpleRibbon;
import corelib.client.ui.widget.toolbar.SimpleRibbonButton;
import corelib.client.ui.widget.toolbar.SimpleRibbonButton.ButtonSize;

public class OrderManager extends PageBase<Widget> {
	
	public final static int MaxRecordsPerPage = 10;
	
	private int currentOffset = 0;
	private int currentRecordsPerPage = 0;
	
	private SimpleRibbon          toolBar;
	private SimpleRibbonButton    nextBtn;
	private SimpleRibbonButton    prevBtn;
	private OrderTableHandler     orderTableHandler;
	private SimpleDataGrid<Order> orderTable;
	private OrderSearchPanel      searchPanel;
	
	public OrderManager() {
		setPageName("销售管理");
		setPageIcon(BoxResources.INSTANCE.order24());
	}
	
	@Override
	protected Widget createWidget() {
		orderTable = createTable();
		toolBar    = createToolBar();
		
		SimpleLayoutPanel panel =  new SimpleLayoutPanel();
		panel.add(toolBar);
		panel.add(orderTable);
		panel.add(searchPanel = new OrderSearchPanel(this, new DataCallback<PagingResult<Order>>(){
			@Override
			public void onCompleted(PagingResult<Order> result) {
				orderTableHandler.setObjects(result.getData());
				currentOffset = result.getOffset();
				currentRecordsPerPage = result.getData().size();
				
				prevBtn.setEnabled(currentOffset > 0);
				nextBtn.setEnabled(currentOffset + currentRecordsPerPage < result.getTotal());
			}
		}));
		
		panel.setWidgetTopHeight(toolBar, 0, Unit.PX, 80, Unit.PX);
		panel.setWidgetTopBottom(orderTable, 80, Unit.PX, 0, Unit.PX);
		return panel;
	}
	
	public SimpleDataGrid<Order> getOrderTable() {
		return this.orderTable;
	}

	@Override
	protected void afterCreateWidget(Widget widgetCreated) {
		super.afterCreateWidget(widgetCreated);
		new DeferredTask().run(new ScheduledCommand(){
			@Override
			public void execute() {
				refresh();
			}
		}, 500);
	}

	private SimpleRibbon createToolBar(){
		SimpleRibbon toolBar = new SimpleRibbon();
		toolBar.addPushButton(new SimpleRibbonButton("创建销售记录",
			BoxResources.INSTANCE.addOrder32(),ButtonSize.Medium,
			new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					SimpleLargeDialog.show(new CreateOrderHandler(new Action(){
						@Override
						public void run() {
							new DeferredTask().run(new ScheduledCommand(){
								@Override
								public void execute() {
									refresh();
								}
							}, 400);;
						}
					}));
				}
			}
		));
		toolBar.addPushButton(new SimpleRibbonButton("快捷创建", 
				BoxResources.INSTANCE.addOrderQuick32(),ButtonSize.Medium,
				new WidgetListener(){
					@Override
					public void valueUpdated(Widget widget) {
						SimpleDialog.show(new CreateQuickOrderHandler(new Action(){
							@Override
							public void run() {
								new DeferredTask().run(new ScheduledCommand(){
									@Override
									public void execute() {
										refresh();
									}
								}, 300);;
							}
						}));
					}
				}
			));
		toolBar.addSeparator(ButtonSize.Medium);
		
		toolBar.addPushButton(new SimpleRibbonButton("更新订单为完成", BoxResources.INSTANCE.updateOrder32(),ButtonSize.Medium,
			new WidgetListener() {
				public void valueUpdated(Widget widget) {
					Order order = orderTable.getSelectedObject();
					if (order != null) {
						SimpleModal.show("努力更新中...");
						Services.OrderService.UpdateOrderStatus(SessionManager.getPassport(), order.getId(), OrderStatues.Complete, new AsyncCallback<Boolean>(){
							@Override
							public void onFailure(Throwable caught) {
								SimpleModal.hide();
								ErrorHandler.handleServiceError(caught);
							}
							
							@Override
							public void onSuccess(Boolean result) {
								SimpleModal.hide();
								if (result == Boolean.TRUE){
									refresh();
								}
								
							}
						});	
					}
					
				}
			}
		)); 
		toolBar.addPushButton(new SimpleRibbonButton("订单包裹查询", BoxResources.INSTANCE.track32(),
			ButtonSize.Medium,
			new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					Order info = orderTable.getSelectedObject();
					if (info != null){
						SimpleDialog.show(new OrderPackageHandler(info, new Action(){
							@Override
							public void run() {
								refresh();
							}
						}));	
					}
				}
			}
		));
		toolBar.addSeparator(ButtonSize.Medium);
		toolBar.addPushButton(new SimpleRibbonButton("取消订单",BoxResources.INSTANCE.deleteOrder32(), ButtonSize.Medium,
				new WidgetListener() {
					@Override
					public void valueUpdated(Widget widget) {
						final Order info = orderTable.getSelectedObject();
						if (info != null) {
							SimpleMessageBox.confirm("确认", "您确定要删除这个订单吗?", 
								new DataCallback<Boolean>() {
									@Override
									public void onCompleted(Boolean data) {
										if (data == Boolean.TRUE){
											delete(info);
										}
									}
								}
							);
						}
					}
				}
		));
		toolBar.addSeparator(ButtonSize.Medium);
		toolBar.addPushButton(new SimpleRibbonButton("重置刷新", CommonResources.INSTANCE.refresh32(),ButtonSize.Medium,
			new WidgetListener(){
				public void valueUpdated(Widget widget) {
					refresh();	
				}
			}
		));
		toolBar.addSeparator(ButtonSize.Medium);
		toolBar.addPushButton(prevBtn = new SimpleRibbonButton("前页", CommonResources.INSTANCE.prev32(),ButtonSize.Medium,
			new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					load(Math.max(currentOffset - MaxRecordsPerPage, 0));
				}
			}
		));
		toolBar.addPushButton(nextBtn = new SimpleRibbonButton("后页", CommonResources.INSTANCE.next32(),ButtonSize.Medium,
			new WidgetListener(){
				@Override
				public void valueUpdated(Widget widget) {
					load(Math.max(currentOffset + MaxRecordsPerPage, 0));
				}
			}
		));
		toolBar.addSeparator(ButtonSize.Medium);
		prevBtn.setEnabled(false);
		nextBtn.setEnabled(false);
		return toolBar;
	}
	
	protected SimpleDataGrid<Order> createTable(){
		return new SimpleDataGrid<Order>(
				MaxRecordsPerPage,
				orderTableHandler = new OrderTableHandler()
	    );
	}
	
	private void refresh() {
		searchPanel.reset();
		load(0);
	}
	
	private void load(int offset){
		SearchOrderRequest request = searchPanel.getSearchRequest();
		request.setOffset(offset);
		request.setLimit(MaxRecordsPerPage);
		SimpleModal.show("努力加载中...");
		
		Services.OrderService.SearchOrders(SessionManager.getPassport(), request,
			new AsyncCallback<PagingResult<Order>>(){
				@Override
				public void onFailure(Throwable caught) {
					SimpleModal.hide();
					ErrorHandler.handleServiceError(caught);
				}
				
				@Override	
				public void onSuccess(PagingResult<Order> result) {
					SimpleModal.hide();
					orderTableHandler.setObjects(result.getData());
					currentOffset = result.getOffset();
					currentRecordsPerPage = result.getData().size();
					prevBtn.setEnabled(currentOffset > 0);
					nextBtn.setEnabled(currentOffset + currentRecordsPerPage < result.getTotal());
				}
			}
		);
	}
	
	private void delete(Order info) {
		SimpleModal.show("努力删除...");
		Services.OrderService.CancelOrder(SessionManager.getPassport(), info.getId(), new AsyncCallback<Boolean>(){
			@Override
			public void onFailure(Throwable caught) {
				SimpleModal.hide();
				ErrorHandler.handleServiceError(caught);
			}
			
			@Override
			public void onSuccess(Boolean result) {
				SimpleModal.hide();
				if(result == Boolean.TRUE){
					load(currentOffset);
				}
			}
		});
	}
	
	private class StatusCellRenderer extends CellRenderer<Order> {
		@Override
		public void render(SimpleDataModel<Order> model,
						   ColumnConfig columnConfig, 
						   int rowIndex, 
						   int colIndex,
						   SafeHtmlBuilder sb) {
			Order info = model.getObject();
			if (info.getStatus() == OrderStatues.Pending){
				sb.append(SimpleLabel.createWarnning("未处理").asSafeHtml());
			}
			else if (info.getStatus() == OrderStatues.Complete){
				sb.append(SimpleLabel.createSuccess("已完成").asSafeHtml());
			}
			else if (info.getStatus() == OrderStatues.Shipping){
				sb.append(SimpleLabel.createPrimary("运输中").asSafeHtml());
			}
			else if (info.getStatus() == OrderStatues.Cancelled){
				sb.append(SimpleLabel.createDanger("取消").asSafeHtml());
			}
			else {
				sb.append(SimpleLabel.createInfo(OrderStatues.getName(info.getStatus())).asSafeHtml());
			}
		}
	}
	
	private class CourierCellRenderer extends CellRenderer<Order> {
		@Override
		public void render(SimpleDataModel<Order> model,
						   ColumnConfig columnConfig, 
						   int rowIndex, 
						   int colIndex,
						   SafeHtmlBuilder sb) {
			int courierId = model.getObject().getCourierId();
			sb.appendHtmlConstant("<div style='padding: 5px; font-weight: bold;'>")
			  .append(Courier.GetImageAsHtml(courierId))
			  .appendHtmlConstant("</div>");
		}
	}
	
	private class OrderTableHandler extends SimpleDataGridHandler<Order> {
		
		public final static String OperatorId 	= "CreatorId";
		public final static String Courier		= "Courier";
		public final static String TrackingId	= "TrackingId";
		public final static String CustomerName = "CustomerName";
		public final static String Status 		= "Status";
		public final static String Cost 		= "Cog";
		public final static String Postage 		= "Postage";
		public final static String TotalPostage = "TotalPostage";
		public final static String Price 		= "Price";
		public final static String Profit       = "Profit";
		public final static String Description  = "Description";
		public final static String DateCreated  = "DateCreated";
		
		List<Order> data;
		
		@Override
		public List<ColumnConfig> createColumns() {
			List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
			configs.add(ColumnConfigs.create(DateCreated, 	"创建日期", 100, DateFormats.YYYY_MM_DD));
			configs.add(ColumnConfigs.create(Courier,  		"快递", 100,    new CourierCellRenderer()));
			configs.add(ColumnConfigs.create(TrackingId,  	"快递查询号", 80));
			configs.add(ColumnConfigs.create(CustomerName,  "收件人", 50));
			configs.add(ColumnConfigs.create(Status, 		"订单状态",  50, new StatusCellRenderer()));
			configs.add(ColumnConfigs.create(OperatorId, 	"操作员",  50));
			configs.add(ColumnConfigs.create(Description,   "物品描述", 100));
			configs.add(ColumnConfigs.create(Cost, 		  	"订单购买成品", 80, NumberFormats.AUD));
			configs.add(ColumnConfigs.create(Postage,     	"订单邮费",       80,  NumberFormats.AUD));
			configs.add(ColumnConfigs.create(TotalPostage,  "订单邮费和库存邮费",80,  NumberFormats.AUD));
			configs.add(ColumnConfigs.create(Price, 		"销售价格",       80,  NumberFormats.RMB));
			configs.add(ColumnConfigs.create(Profit, 	    "估计利润" ,      80,  NumberFormats.RMB));
			return configs;
		}

		@Override
		public void format(int index, SimpleDataModel<Order> model) {
			Order info = model.getObject();
			model.set(OperatorId, 	ApplicationContext.getUser(info.getOperatorId()).getName());
			model.set(Courier, 	    info.getCourierId());
			model.set(Status, 	    info.getStatus());
			model.set(TrackingId, 	info.getTrackingId());
			model.set(CustomerName, info.getCustomerName());
			model.set(Description,	Util.getString(info.getDescription()));
			model.set(Cost, 		info.getCost());
			model.set(Postage,  	info.getPostage());
			model.set(TotalPostage, info.getTotalPostage());
			model.set(Price, 		info.getPrice());
			model.set(Profit, 	    info.getProfit());
			model.set(DateCreated,  info.getDateCreated());
		}
		
		public void setObjects(List<Order> objects){
			this.data = objects;
			this.getGrid().setObjects(objects);
		}
		
		@Override
		public List<Order> getObjects() {
			return this.data;
		}

		@Override
		public void onObjectClicked(Order obj) {
		}

		@Override
		public void onObjectDoubleClicked(Order obj) {
			onObjectClicked(obj);
		}
		
	}
}
